組込み現場の「C++」プログラミング 明日から使える徹底入門

高木 信尚(株式会社クローバーフィールド

4.2 Embedded C++と標準C++

C++には標準C++のほかに,組込み向けC++ということで作られたEmbedded C++(EC++)というものがあります.組込み開発におけるC++を語るうえでは知っておくべきですので,簡単に紹介するとともに,標準C++との比較も行うことにします.

4.2.1 Embedded C++の概要

EC++は標準C++のサブセットを目指した規格で,以下の内容にポイントを置いて言語仕様が策定されたようです.

  • オブジェクト指向的に有用な部分は残しつつ,複雑な機能は削除
  • 組込みシステム設計の要求を満たさない機能は削除
  • 過度のメモリ消費を要求するもの
  • 応答の予測が難しいもの
  • コードのROM化を妨げるもの
  • ANSI/ISO C++言語規格で,まだ仕様が確定していない機能は削除

具体的には以下の仕様が削除されています.

  • mutable指定子*4
  • 例外処理
  • 実行時型識別
  • 名前空間
  • テンプレート
  • 多重継承と仮想継承
  • wchar_tとlong doubleのためのライブラリ
  • 国際文字名*5
  • 新しいキャスト

さらには,テンプレートが削除されたことで,STLをはじめとする標準C++ライブラリの大多数が削除されることになりました.結果として,C++の黎明期とさほど変わらないような状態まで,言語仕様がコンパクトになっています.

*4 const修飾されたクラス型のオブジェクトであっても,データメンバーを更新可能にするための記憶クラス指定子です.

*5 C++やC99では,文字コードに依存せずに拡張文字集合を扱えるように,ISO 10646文字集合の文字を16進数で直接指定することができます.たとえばひらがなの「あ」であれば,16ビットで\u3042または32ビットで\U00003042と表記することができます.国際文字名は,文字定数や文字列リテラルだけでなく,識別子(すなわち関数名や変数名など)にも使用することができます.ただし,実際に国際文字名をサポートしている処理系は稀であるため,移植性に配慮するなら国際文字名の使用は避けたほうが無難です.

4.2.2 Embedded C++を使ううえでの注意点

EC++か標準C++かの判別は,__embedded_cplusplusマクロの定義状態で判別することができます.EC++は標準C++のサブセットを目指していましたが,現実には互換性のない部分がかなりあります.そのため,両方に対応するコードを書く際には,条件付きコンパイルが必須です.

まず,EC++は名前空間がサポートされていないため,ライブラリ機能を使おうとするとシンタックスに一貫性がなくなります.たとえば,標準C++ではstd::size_tと書きますが,EC++は単にsize_tと書かなければなりません.をインクルードしようにもEC++ではサポートされていません.

次のようなマクロを定義することで,互換性のあるコードを書くこともできないわけではありませんが,細部の振る舞いが異なることや,std::を付け忘れてもエラーを検出できないことなど,問題は少なくありません.

#define std

次に,組込み環境の多くはフリースタンディング環境に該当しますが,標準C++ではサポートされないライブラリの多くがEC++ではサポートされています.つまり,EC++で実装されたコードをそのまま標準C++に持っていっても,ライブラリが不足しているために使えないことがあるのです.

最後に,EC++は例外処理をサポートしていないため,EC++で実装されたコードは例外安全をはじめとする例外処理の影響に配慮されていないと考えられます.したがって,そうしたコードを標準C++に持っていっても,信頼性に大きな問題があります.

このように,EC++は標準C++のサブセットであると考えるより,まったく別の言語だと考えたほうがよさそうです.ただ,テンプレートと例外処理を使うつもりがないのであれば,「ベターC」(より良いC)として使うには手軽で便利な言語であるといえます.

なお,最近では,Embedded C++にテンプレートなどの仕様を追加した,拡張Embedded C++と呼ばれる方言をコンパイラがサポートしていることもあります.